<template>
	<view @click="showCity = !props.disabled ? !showCity : false">
		<!-- #ifdef APP-NVUE -->
		<view :eventPenetrationEnabled="true">
			<slot></slot>
		</view>
		<!-- #endif -->
		<!-- #ifndef APP-NVUE -->
		<slot></slot>
		<!-- #endif -->
		<zh-drawer :zIndex="props.zIndex" :inContent="props.inContent" :disabbleScroll="true" :round="props.round" ref="drawer"
			:height="dHeight" :closeable="true" placement="bottom" :overlayClick="true" @open="drawerOpen"
			:duration="100" @cancel="cancel" @ok="confirm" :show="showCity" :okColor="_color" title="请选择" ok-text="确认">
			<template #title v-if="props.showSearch">
				<zh-input suffix="tmicon-search" placeholder="请输入搜索内容" :showClear="true" v-model="searchText"
					:transprent="false" style="width: 500rpx"></zh-input>
			</template>
			<zh-scrolly v-show="props.columns && props.columns.length > 0" :height="dHeight - (store.orientation === 'landscape'?180:220)" :openPull="false">
				<zh-tree ref="zhTreeRef" :data="props.columns" :checkStrictly="props.checkStrictly"
					:checkable="props.checkable" :fieldNames="myFieldNames" :multiple="props.mode === 'multiple'"
					v-model:selected-id="value" :expandedAll="props.expandedAll" :queryParams="props.queryParams"
					:cryptoEnabled="props.cryptoEnabled" :repeatEnabled="props.repeatEnabled" @nodeClick="nodeClicked"
					:desensitizeFlag="props.desensitizeFlag" :timeout="props.timeout"></zh-tree>
			</zh-scrolly>
			<zh-result v-if="!props.columns || props.columns.length <= 0" :showBtn="false" title="没有可供选择的数据"
				subTitle="请重新输入关键字搜索"></zh-result>
			<zh-button v-if="props.columns && props.columns.length > 0" :height="64" label="确认选择" block :margin="[32, 12]"
					:color="_color" :linear="props.linear" :linear-deep="props.linearDeep" @click="confirm"
				:round="props.btnRound">
			</zh-button>
			<view :style="{ height: sysinfo.bottomSafe + 'px' }"></view>
		</zh-drawer>
	</view>
</template>
<script lang="ts" setup>
	import { PropType, Ref, ref, watchEffect, onMounted, getCurrentInstance, computed, toRaw, inject, nextTick, watch } from 'vue';
	import { queryNodeStr } from '../zh-tree/util';
	import { custom_props } from '@/tool/lib/minxs';
	import { useWindowInfo } from '@/tool/useFun/useWindowInfo'
	import systemConfigStore from '@/store/modules/systemConfigStore';
	const store = systemConfigStore();
	const drawer = ref<any>(null);
	const emits = defineEmits(['update:show', 'update:modelValue', 'update:modelStr', 'confirm', 'cancel', 'close', 'open', 'search']);
	const props = defineProps({
		...custom_props,
		fieldNames: {
			type: Object,
			default: () => {
				return { label: 'title', value: 'key', children: 'children' };
			},
		},
		zIndex: {
			type: [Number, String],
			default: 999,
		},
		lazy: {
			type: Boolean,
			default: false,
		},
		//	使单选模式可搜索
		showSearch: {
			type: Boolean,
			default: true,
		},
		//可v-model,每一列选中的索引值
		modelValue: {
			type: [Number, String, Boolean, Array],
			default: undefined,
		},

		/**
		 * 注意：这里是单向输出显示的value值，而不是modelValue的index索引值。
		 * 这里主要是为了方便表单上页面的显示。如果真要保存到数据库，你应该保存modelValue的值。
		 */
		modelStr: {
			type: [String],
			default: '',
		},
		//默认选中的索引值。
		defaultValue: {
			type: [Number, String, Boolean, Array],
			default: undefined,
		},
		//赋值和选值方式
		//name:名称模式赋值和选择
		//id:id模式赋值和选择
		//index:索引模式赋值和选择
		selectedModel: {
			type: String,
			default: 'id',
		},
		max: {
			type: Number,
			default: 99,
		},
		//数据。
		columns: {
			type: Array as PropType<Array<any>>,
			default: () => [],
			required: true,
		},
		//当前改变index项时，改变时执行的函数。如果返回false，将会阻止本次改变,可以是Promise
		//提供了即将改变的数据和将要改变到目标的数据
		//结构 为 from:{itemindex,levelIndex,data},to:{itemindex,levelIndex,data}。
		beforeChange: {
			type: [Boolean, Function],
			default: () => false,
		},
		//v-model:show来双向绑定显示和隐藏选择器。
		show: {
			type: [Boolean],
			default: false,
		},
		color: {
			type: String,
			default: 'primary',
		},
		linear: {
			type: String,
			default: '',
		},
		linearDeep: {
			type: String,
			default: 'light',
		},
		btnRound: {
			type: Number,
			default: 3,
		},
		round: {
			type: Number,
			default: 3,
		},
		height: {
			type: Number,
			default: 700,
		},
		immediateChange: {
			type: Boolean,
			default: false,
		},
		/** 是否嵌入弹层，开启后将在它的父组件内执行弹层。 */
		inContent: {
			type: Boolean,
			default: false,
		},
		//模式：单选或者多选multiple
		mode: {
			type: String,
			default: 'single',
		},
		funcCode: {
			type: String,
			default: '',
		},
		url: {
			type: String,
			default: '',
		},
		queryParams: {
			type: Object,
			default: () => { },
		},
		//是否展开所有
		expandedAll: {
			type: Boolean,
			default: false,
		},
		//在显示复选框的情况下，是否严格的遵循父子不互相关联的做法，默认为 false
		checkStrictly: {
			type: Boolean,
			default: false,
		},
		//允许在节点前添加复选框。
		checkable: {
			type: Boolean,
			default: true,
		},
		/**禁用时，通过插槽点击时，不会触发显示本组件，适合表单 */
		disabled: {
			type: Boolean,
			default: false,
		},
		timeout: Number,
		//是否加密
		cryptoEnabled: {
			type: Boolean,
			default: false
		},
		//是否脱敏
		desensitizeFlag: {
			type: Boolean,
			default: false
		},
		//是否防重复提交
		repeatEnabled: {
			type: Boolean,
			default: false
		},
	});
	const myFieldNames = ref({ id: props.fieldNames.value, text: props.fieldNames.label });
	const zhTreeRef = ref();
	const showCity = ref(props.show);
	const searchText = ref('');
	const aniover = ref(true);
	const value = ref<any>([]);
	const _strvalue = ref(props.modelStr);
	const sysinfo = useWindowInfo()
	const _color = computed(() => {
		let color = props.color;
		if (props.followTheme && store.color) {
			color = store.color;
		}
		return color;
	});
	const selectItem = ref({})
	onMounted(() => {
		if (props.modelValue && props.modelValue.length > 0) {
			if (typeof props.modelValue == 'string') {
				let list = [];
				list.push(props.modelValue);
				value.value = list;
			} else {
				value.value = props.modelValue;
			}
			nextTick(() => {
				defaultModerStrGet();
			});
		}
	});
	function defaultModerStrGet() {
		let strList = [];
		if (zhTreeRef.value) {
			strList = zhTreeRef.value.getNodeStr();
		} else {
			strList = queryNodeStr(props.columns, value.value, myFieldNames.value.id, myFieldNames.value.text);
		}
		let strValue = '';
		if (strList && strList.length > 0) {
			strList.forEach((item : any) => {
				if (!strValue) {
					strValue = item;
				} else {
					strValue = strValue + ',' + item;
				}
			});
		}
		emits('update:modelStr', strValue);
	}
	//点击确认了。
	function confirm() {
		nextTick(() => {
			defaultModerStrGet();

			if (props.mode === 'multiple') {
				emits('confirm', value.value);
				emits('update:modelValue', value.value);
			} else {
				if(selectItem.value.isLeaf){
					if (value.value && value.value.length > 0) {
						emits('confirm', value.value[0]);
						emits('update:modelValue', value.value[0]);
					} else {
						emits('confirm', null);
						emits('update:modelValue', null);
					}
				}else{
					return;
				}
			}
			showCity.value = false;
			emits('update:show', showCity.value);
		});
	}
	function cancel() {
		if (typeof props.modelValue == 'string') {
			let list = [];
			list.push(props.modelValue);
			value.value = list;
		} else {
			value.value = props.modelValue;
		}
		showCity.value = false;
		emits('update:show', showCity.value);
		emits('cancel');
	}
	function onSearch() {
		zhTreeRef.value.searchData(searchText.value);
	}
	function closeDrawer(e : boolean) {
		showCity.value = e;
		emits('update:show', showCity.value);
		emits('close');
	}
	//弹层打开时触发。
	function drawerOpen() {
		emits('open');
	}
	const dHeight = computed(() => {
		return props.height + sysinfo.bottomSafe;
	});

	function onPullFun(type : any) {
		emits('search', searchText.value, type);
	}
	function nodeClicked(item: any) {
		value.value[0] = item.id
		if(item.isLeaf){
			selectItem.value = item
		}else{
			selectItem.value.isLeaf = false
		}
	}

	watch(
		() => props.modelValue,
		() => {
			if (typeof props.modelValue == 'string') {
				let list = [];
				list.push(props.modelValue);
				value.value = list;
			} else {
				value.value = props.modelValue;
			}
			defaultModerStrGet();
		},
		{ deep: true }
	);
	watch(
		() => props.columns,
		() => {
			nextTick(() => {
				defaultModerStrGet();
			});
		},
		{ deep: true }
	);
	watch(
		() => searchText.value,
		(val) => {
			onSearch();
		},
		{ deep: true }
	);
	watch(
		() => props.show,
		(val) => {
			showCity.value = val;
		},
		{ deep: true }
	);
</script>

<style scoped></style>